package image.noise.generators;

import image.processing.ImageProcessor;
import image.processing.ImageProcessor.CompressAlgorithm;

import java.awt.image.BufferedImage;
import java.awt.image.WritableRaster;

import random.generators.RandomUtils;
/**
 * Generardor de ruido sal y pimienta
 * @author chiche
 *
 */
public class SaltAndPepperNoise {
	double p0;
	double p1;
	public SaltAndPepperNoise(double p0,double p1) {
		if(p0 > p1){
			throw new IllegalArgumentException();
		}
		this.p0 = p0;
		this.p1 = p1;
	}
	/**
	 * Es mejor llamarlo con javaDefault porque los valores nunca se van de rango (0-255)
	 * @param img
	 * @param algorithm
	 * @return
	 */
	public BufferedImage addNoise (BufferedImage img, CompressAlgorithm algorithm){
		BufferedImage ans;
		int color;

		if (img == null) {
			return null;
		} else {
			if (img.getType() == BufferedImage.TYPE_BYTE_GRAY) {

				ans = new BufferedImage(img.getWidth(), img.getHeight(),
						BufferedImage.TYPE_BYTE_GRAY);
				WritableRaster raster = ans.getRaster();
				int intValues[][] = new int[img.getWidth()][img.getHeight()];
				for (int x = 0; x < img.getHeight(); x++) {
					for (int y = 0; y < img.getWidth(); y++) {
						double rand =  Math.random();
						if(rand <= p0){
							intValues[x][y] = 0;
						}else if( rand >= p1){
							intValues[x][y] = 255;
						}else{
							intValues[x][y] = img.getRaster().getSample(x, y, 0);
						}
			
					}
				}
				if (algorithm == CompressAlgorithm.DYNAMIC) {
					intValues = ImageProcessor.DynamicRangeCompressionChannel(intValues);
				} else if (algorithm == CompressAlgorithm.LINEAR) {
					intValues = ImageProcessor.LinearRangeCompressionChannel(intValues);
				}
				for (int x = 0; x < img.getWidth(); x++) {
					for (int y = 0; y < img.getHeight(); y++) {
						raster.setSample(x, y, 0, intValues[x][y]);
					}
				}
			} else {
				ans = new BufferedImage(img.getWidth(), img.getHeight(),
						BufferedImage.TYPE_3BYTE_BGR);
				WritableRaster raster = ans.getRaster();
				WritableRaster originalRaster = img.getRaster();
				double rand =  Math.random();
				int intValues0[][] = new int[img.getWidth()][img.getHeight()];
				int intValues1[][] = new int[img.getWidth()][img.getHeight()];
				int intValues2[][] = new int[img.getWidth()][img.getHeight()];
				for (int x = 0; x < img.getWidth(); x++) {
					for (int y = 0; y < img.getHeight(); y++) {
						if(rand <= p0){
							intValues0[x][y] = 0;
							intValues1[x][y] = 0;
							intValues2[x][y] = 0;
						}else if( rand >= p1){
							intValues0[x][y] = 255;
							intValues1[x][y] = 255;
							intValues2[x][y] = 255;
						}else{
							intValues0[x][y] = originalRaster.getSample(x, y, 0);;
							intValues1[x][y] = originalRaster.getSample(x, y, 1);
							intValues2[x][y] = originalRaster.getSample(x, y, 2);
						}

					}
				}
				if (algorithm == CompressAlgorithm.DYNAMIC) {
					intValues0 = ImageProcessor.DynamicRangeCompressionChannel(intValues0);
					intValues1 = ImageProcessor.DynamicRangeCompressionChannel(intValues1);
					intValues2 = ImageProcessor.DynamicRangeCompressionChannel(intValues2);
				} else if (algorithm == CompressAlgorithm.LINEAR) {
					intValues0 = ImageProcessor.LinearRangeCompressionChannel(intValues0);
					intValues1 = ImageProcessor.LinearRangeCompressionChannel(intValues1);
					intValues2 = ImageProcessor.LinearRangeCompressionChannel(intValues2);
				}
				for (int x = 0; x < img.getWidth(); x++) {
					for (int y = 0; y < img.getHeight(); y++) {
						raster.setSample(x, y, 0, intValues0[x][y]);
						raster.setSample(x, y, 1, intValues1[x][y]);
						raster.setSample(x, y, 2, intValues2[x][y]);
					}
				}
			}

			return ans;
		}}
	
	
}
